package scales.xml.xpath
import scales.xml._
import impl.EqualsHelpers
import impl.IsFromParser
import dsl.DslBuilder
import scales.utils._
trait Names[T] {
def name(implicit t : T) : Option[QName]
protected[xml] def flatName(implicit t : T) : QName =
name(t).getOrElse(EmptyQName.empty)
}
class DIF()
protected[xml] object EmptyQName {
protected[xml] val empty = NoNamespaceQName("")(Xml10, IsFromParser)
}
trait Functions extends NameFunctions with TextFunctions {
def hasLocalNameX( local : String ) : XmlPath => Boolean =
(x : XmlPath) => hasLocalName[XmlPath](local)(XmlPathNames)(x)
def hasLocalNameA( local : String ) : AttributePath => Boolean =
(x : AttributePath) => hasLocalName[AttributePath](local)(AttributePathNames)(x)
}
trait NameFunctions {
private[NameFunctions] implicit def toQNameNF[T]( t : T )(implicit name : Names[T]) =
name.flatName(t)
def localName[T](implicit t : T, name : Names[T], d : DIF) : String =
t.local
def localName[T](t : T)(implicit name : Names[T]) : String =
localName(t, name, DIF.dif)
def hasLocalName[T](localName : String)(implicit name : Names[T] ) : T => Boolean =
(t : T) => t.local == localName
def isExactly[T](qname : QName)(implicit name : Names[T] ) : T => Boolean =
(t : T) => t ==== qname
def isEquivalent[T](qname : QName)(implicit name : Names[T] ) : T => Boolean =
(t : T) => t =:= qname
def qname[T](implicit t : T, name : Names[T], d : DIF) : String =
t.qName
def qname[T](t : T)(implicit name : Names[T]) : String =
qname(t, name, DIF.dif)
def qName[T](implicit t : T, name : Names[T], d : DIF) : String =
qname(t, name, DIF.dif)
def qName[T](t : T)(implicit name : Names[T]) : String =
qname(t, name, DIF.dif)
private[this] def testNonEmpty( r : QName ) =
if (r eq EmptyQName.empty)
error("A Names instance has returned the EmptyQName. This is not directly accessable")
else
r
def name[T](implicit t : T, name : Names[T], d : DIF) : QName =
testNonEmpty(t)
def name[T](t : T)(implicit iname : Names[T]) : QName =
name(t, iname, DIF.dif)
def hasQName[T](implicit t : T, name : Names[T], d : DIF) : Boolean =
name.name(t).isDefined
def hasQName[T](t : T)(implicit name : Names[T]) : Boolean =
hasQName(t, name, DIF.dif)
def qualifiedName[T](implicit t : T, name : Names[T], d : DIF) : String =
t.qualifiedName
def qualifiedName[T](t : T)(implicit name : Names[T]) : String =
qualifiedName(t, name, DIF.dif)
def pqName[T](implicit t : T, name : Names[T], d : DIF) : String =
t.pqName
def pqName[T](t : T)(implicit name : Names[T]) : String =
pqName(t, name, DIF.dif)
def namespace[T](implicit t : T, name : Names[T], d : DIF) : UnderlyingNamespace =
t.namespace
def hasNamespace[T](namespace : Namespace)(implicit name : Names[T]) : T => Boolean =
(t : T) => t.namespace == namespace
def namespaceUri[T](implicit t : T, name : Names[T], d : DIF) : String =
t.namespace.uri
def namespaceUri[T](t : T)(implicit name : Names[T]) : String =
t.namespace.uri
def hasNamespace[T](namespaceUri : String)(implicit name : Names[T], d: DIF) : T => Boolean =
(t : T) => t.namespace.uri == namespaceUri
}
trait FunctionImplicits extends TextImplicits with NamesImplicits
object DIF {
val dif = new DIF()
}
trait NamesImplicits {
implicit val dif = DIF.dif
implicit val attribNames = AttributeNames
implicit val attributePathNames = AttributePathNames
implicit val xpathNames = XmlPathNames
implicit val elemNames = ElemNames
implicit val xtreeNames = XmlTreeNames
implicit val qnameNames = QNameNames
implicit val aqnameNames = AQNameNames
implicit val dslNames = DslNames
implicit def attribPathsNames[T <: Iterable[XmlPath]] = AttributePathsNames.asInstanceOf[Names[AttributePaths[T]]]
implicit def xpathToNames[T <: Iterable[XmlPath]] = XPathNames.asInstanceOf[Names[XPath[T]]]
}
object AttributeNames extends Names[Attribute] {
def name(implicit t : Attribute) : Option[QName] = Some(EqualsHelpers.toQName(t.name))
}
object AttributePathsNames extends Names[AttributePaths[_]] {
def name(implicit a : AttributePaths[_]) = {
val r = a.attributes
r.headOption.map( x => EqualsHelpers.toQName( x.attribute.name ))
}
}
object AttributePathNames extends Names[AttributePath] {
def name(implicit t : AttributePath) : Option[QName] = Some(EqualsHelpers.toQName(t.attribute.name))
}
object ElemNames extends Names[Elem] {
def name(implicit t : Elem) : Option[QName] = Some(t.name)
}
object XmlTreeNames extends Names[XmlTree] {
def name(implicit t : XmlTree) : Option[QName] = Some(t.section.name)
}
object DslNames extends Names[DslBuilder] {
def name(implicit t : DslBuilder) : Option[QName] = Some(t.toTree.section.name)
}
object XmlPathNames extends Names[XmlPath] {
def name(implicit t : XmlPath) : Option[QName] = Some(t.tree.section.name)
}
object QNameNames extends Names[QName] {
def name(implicit t : QName) : Option[QName] = Some(t)
}
object AQNameNames extends Names[AttributeQName] {
def name(implicit t : AttributeQName) : Option[QName] = Some(EqualsHelpers.toQName(t))
}
object XPathNames extends Names[XPath[_]] {
def name(implicit a : XPath[_]) = {
val r = ScalesXml.fromXPathToIterable(a)
r.headOption.flatMap(_.focus(_ => None, t => XmlTreeNames.name(t)))
}
}
trait TextValue[T] {
def text(implicit t : T) : String
}
trait TextFunctions {
def text[T](implicit t : T, value : TextValue[T], d : DIF ) : String =
value.text
def string[T](implicit t : T, value : TextValue[T], d : DIF ) : String =
text(t, value, DIF.dif)
def value[T](implicit t : T, value : TextValue[T], d : DIF ) : String =
text(t, value, DIF.dif)
def normalizeSpace[T](implicit t : T, value : TextValue[T], d : DIF ) : String =
normalizeSpaceS(value.text)
def text[T](t : T)(implicit value : TextValue[T]) : String =
text(t, value, DIF.dif)
def string[T](t : T)(implicit value : TextValue[T]) : String =
text(t, value, DIF.dif)
def value[T](t : T)(implicit value : TextValue[T] ) : String =
text(t, value, DIF.dif)
def normalizeSpace[T](t : T)(implicit value : TextValue[T] ) : String =
normalizeSpaceS(value.text(t))
}
trait TextImplicits {
implicit val xtreeText = XmlTreeText
implicit val attribText = AttributeText
implicit val attribPathText = AttributePathText
implicit val xmlpathText = XmlPathText
implicit val itemText = XmlItemText
implicit val itemOrElemText = ItemOrElemText
implicit val dslText = DslText
implicit def attribPathsText[T <: Iterable[XmlPath]] = AttributePathsText.asInstanceOf[TextValue[AttributePaths[T]]]
implicit def xpathToTextValue[T <: Iterable[XmlPath]] = XPathText.asInstanceOf[TextValue[XPath[T]]]
}
object XmlTreeText extends TextValue[XmlTree] {
def text(implicit t: XmlTree): String = {
t.fold(new StringBuilder())
{ (walker, sb) =>
if (walker.isLeft) {
walker.left.get match {
case Text(text) => sb.append(text)
case CData(text) => sb.append(text)
case _ => ()
}
}
sb
}.toString
}
}
object DslText extends TextValue[DslBuilder] {
def text(implicit t : DslBuilder) = XmlTreeText.text(t.toTree)
}
object XmlPathText extends TextValue[XmlPath] {
def text(implicit t : XmlPath) =
t.focus(_.value, XmlTreeText.text(_))
}
object ItemOrElemText extends TextValue[ItemOrElem] {
def text(implicit t : ItemOrElem) =
t.fold(_.value, XmlTreeText.text(_))
}
object AttributeText extends TextValue[Attribute] {
def text(implicit a : Attribute) = a.value
}
object AttributePathText extends TextValue[AttributePath] {
def text(implicit a : AttributePath) = a.attribute.value
}
object AttributePathsText extends TextValue[AttributePaths[_]] {
def text(implicit a : AttributePaths[_]) =
if (a.attributes.size == 0) ""
else a.attributes.head.attribute.value
}
object XmlItemText extends TextValue[XmlItem] {
def text(implicit a : XmlItem) = a.value
}
object XPathText extends TextValue[XPath[_]] {
def text(implicit a : XPath[_]) = {
val r = ScalesXml.fromXPathToIterable(a)
if (r.size == 0) ""
else XmlPathText.text( r.head )
}
}